package cn.edu.wfit.modules.infomanagement.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import cn.edu.wfit.api.domain.system.SysRole;
import cn.edu.wfit.api.domain.system.SysUser;
import cn.edu.wfit.common.core.constant.UserConstants;
import cn.edu.wfit.common.core.exception.ServiceException;
import cn.edu.wfit.common.core.text.Convert;
import cn.edu.wfit.common.core.utils.DateUtils;
import cn.edu.wfit.common.core.utils.StringUtils;
import cn.edu.wfit.common.core.utils.bean.BeanValidators;
import cn.edu.wfit.modules.infomanagement.domain.Cls;
import cn.edu.wfit.modules.infomanagement.mapper.ClsMapper;
import jakarta.validation.Validator;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import cn.edu.wfit.modules.infomanagement.mapper.StudentMapper;
import cn.edu.wfit.modules.infomanagement.domain.Student;
import cn.edu.wfit.modules.infomanagement.service.IStudentService;
import org.springframework.util.CollectionUtils;

/**
 * 学生管理Service业务层处理
 * 
 * @author 韩强
 * @date 2024-11-20
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class StudentServiceImpl implements IStudentService 
{
    private final StudentMapper studentMapper;
    private final ClsMapper clsMapper;
    private final Validator validator;

    /**
     * 查询学生管理
     * 
     * @param userId 学生管理主键
     * @return 学生管理
     */
    @Override
    public Student selectStudentByUserId(Long userId)
    {
        return studentMapper.selectStudentByUserId(userId);
    }

    /**
     * 查询学生管理列表
     * 
     * @param student 学生管理
     * @return 学生管理
     */
    @Override
    public List<Student> selectStudentList(Student student)
    {
        return studentMapper.selectStudentList(student);
    }

    /**
     * 新增学生管理
     * 
     * @param student 学生管理
     * @return 结果
     */
    @Override
    public int insertStudent(Student student)
    {
        if (Objects.isNull(student.getClsId())){
            throw new ServiceException("请选择班级");
        }
        Cls cls = clsMapper.selectClsByClsId(student.getClsId());
        if (Objects.isNull(cls)){
            throw new ServiceException("没有找到班级相关信息");
        }
        student.setCampusId(cls.getCampusId());
        student.setClsId(cls.getClsId());
        student.setClsName(cls.getClsName());
        student.setCollegeId(cls.getCollegeId());
        student.setCollegeName(cls.getCollegeName());
        student.setMajorId(cls.getMajorId());
        student.setMajorName(cls.getMajorName());
        student.setCreateTime(DateUtils.getNowDate());
        BeanValidators.validateWithException(validator, student);
        return studentMapper.insertStudent(student);
    }

    /**
     * 修改学生管理
     * 
     * @param student 学生管理
     * @return 结果
     */
    @Override
    public int updateStudent(Student student)
    {
        if (Objects.isNull(student.getClsId())){
            throw new ServiceException("请选择班级");
        }
        Cls cls = clsMapper.selectClsByClsId(student.getClsId());
        if (Objects.isNull(cls)){
            throw new ServiceException("没有找到班级相关信息");
        }
        student.setCampusId(cls.getCampusId());
        student.setClsId(cls.getClsId());
        student.setClsName(cls.getClsName());
        student.setCollegeId(cls.getCollegeId());
        student.setCollegeName(cls.getCollegeName());
        student.setMajorId(cls.getMajorId());
        student.setMajorName(cls.getMajorName());
        student.setCreateTime(DateUtils.getNowDate());
        BeanValidators.validateWithException(validator, student);
        student.setUpdateTime(DateUtils.getNowDate());
        return studentMapper.updateStudent(student);
    }

    /**
     * 批量删除学生管理
     * 
     * @param userIds 需要删除的学生管理主键
     * @return 结果
     */
    @Override
    public int deleteStudentByUserIds(Long[] userIds)
    {
        return studentMapper.deleteStudentByUserIds(userIds);
    }

    /**
     * 删除学生管理信息
     * 
     * @param userId 学生管理主键
     * @return 结果
     */
    @Override
    public int deleteStudentByUserId(Long userId)
    {
        return studentMapper.deleteStudentByUserId(userId);
    }

    /**
     * 导入学生
     *
     * @param studentList     学生数据列表
     * @param isUpdateSupport 是否更新支持，如果已存在，则进行更新数据
     * @param operName        操作用户
     * @return
     */
    @Override
    public String importUser(List<Student> studentList, Boolean isUpdateSupport, String operName) {
        if (CollectionUtils.isEmpty(studentList))
        {
            throw new ServiceException("导入用户数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (Student importStudent : studentList){
            try {
                Student student = studentMapper.selectStudentByUserCode(importStudent.getStuCode());
                if(Objects.isNull(student)){
                    BeanValidators.validateWithException(validator, importStudent);
                    studentMapper.insertStudent(importStudent);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、学生 " + importStudent.getRealname()+"("+importStudent.getStuCode() + ") 导入成功");
                }
                else
                {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、学生 " + importStudent.getRealname()+"("+importStudent.getStuCode() + ") 已存在");
                }

            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、学生 " + importStudent.getRealname()+"("+importStudent.getStuCode() + ") 导入失败：";
                failureMsg.append(msg + e.getMessage());
                log.error(msg, e);
            }
        }
        if (failureNum > 0)
        {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        }
        else
        {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }
    private String dataScopeFilter( SysUser user)
    {
        /**
         * 全部数据权限
         */
        final String DATA_SCOPE_ALL = "1";

        /**
         * 自定数据权限
         */
        final String DATA_SCOPE_CUSTOM = "2";

        /**
         * 部门数据权限
         */
        final String DATA_SCOPE_DEPT = "3";

        /**
         * 部门及以下数据权限
         */
        final String DATA_SCOPE_DEPT_AND_CHILD = "4";

        /**
         * 仅本人数据权限
         */
       final String DATA_SCOPE_SELF = "5";

        /**
         * 数据权限过滤关键字
         */
        final String DATA_SCOPE = "dataScope";
        String str ="";
        StringBuilder sqlString = new StringBuilder();
        List<String> conditions = new ArrayList<String>();
        List<String> scopeCustomIds = new ArrayList<String>();
        user.getRoles().forEach(role -> {
            if (DATA_SCOPE_CUSTOM.equals(role.getDataScope()) && StringUtils.equals(role.getStatus(), UserConstants.ROLE_NORMAL))
            {
                scopeCustomIds.add(Convert.toStr(role.getRoleId()));
            }
        });

        for (SysRole role : user.getRoles())
        {
            String dataScope = role.getDataScope();
            if (conditions.contains(dataScope) || StringUtils.equals(role.getStatus(), UserConstants.ROLE_DISABLE))
            {
                continue;
            }
            if (DATA_SCOPE_ALL.equals(dataScope))
            {
                sqlString = new StringBuilder();
                conditions.add(dataScope);
                break;
            }
            else if (DATA_SCOPE_CUSTOM.equals(dataScope))
            {
                if (scopeCustomIds.size() > 1)
                {
                    // 多个自定数据权限使用in查询，避免多次拼接。
                    if(user.isCollegeTeacher()){
                    sqlString.append(StringUtils.format(" OR teacher_id IN ( SELECT user_id FROM sys_user WHERE dept_id IN( SELECT dept_id FROM sys_role_dept WHERE role_id in ({}))) ",  String.join(",", scopeCustomIds)));
                    }else if (user.isCounselorTeacher()){
                        sqlString.append(StringUtils.format(" OR counselor_id IN ( SELECT user_id FROM sys_user WHERE dept_id IN( SELECT dept_id FROM sys_role_dept WHERE role_id in ({}))) ",  String.join(",", scopeCustomIds)));
                    }
                }
                else
                {
                    if(user.isCollegeTeacher()){
                        sqlString.append(StringUtils.format(" OR teacher_id IN ( SELECT user_id FROM sys_user WHERE dept_id IN( SELECT dept_id FROM sys_role_dept WHERE role_id = ({})) ) ",  role.getRoleId()));

                    }else if (user.isCounselorTeacher()){
                        sqlString.append(StringUtils.format(" OR counselor_id IN ( SELECT user_id FROM sys_user WHERE dept_id IN( SELECT dept_id FROM sys_role_dept WHERE role_id = ({})) ) ",  role.getRoleId()));

                    }
                }
            }
            else if (DATA_SCOPE_DEPT.equals(dataScope))
            {
                if(user.isCollegeTeacher()){
                    sqlString.append(StringUtils.format(" OR teacher_id IN ( SELECT user_id FROM sys_user WHERE dept_id ={}) ",  user.getDeptId()));

                }else if (user.isCounselorTeacher()){
                    sqlString.append(StringUtils.format(" OR counselor_id IN ( SELECT user_id FROM sys_user WHERE dept_id ={}) ",  user.getDeptId()));

                }
            }
            else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope))
            {
                if(user.isCollegeTeacher()){
                    sqlString.append(StringUtils.format(" OR teacher_id IN ( SELECT user_id FROM sys_user WHERE dept_id IN( ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set({}, ancestors) > 0 )) )",  user.getDeptId(), user.getDeptId()));

                }else if (user.isCounselorTeacher()){
                    sqlString.append(StringUtils.format(" OR counselor_id IN ( SELECT user_id FROM sys_user WHERE dept_id IN( ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set({}, ancestors) > 0 )) )",  user.getDeptId(), user.getDeptId()));

                }
            }
            else if (DATA_SCOPE_SELF.equals(dataScope))
            {
                if(user.isCollegeTeacher()){
                    sqlString.append(StringUtils.format(" OR teacher_id = {} ",  user.getUserId()));

                }else if (user.isCounselorTeacher()){
                    sqlString.append(StringUtils.format(" OR counselor_id = {} ",  user.getUserId()));

                }
            }
            conditions.add(dataScope);
        }


        if (StringUtils.isNotBlank(sqlString.toString()))
        {

            str =" AND (" + sqlString.substring(4) + ")";

        }
        return str;
    }
}
